package stl_interface_ext

import "strconv"

func IsNull(value interface{}) bool {
	switch value.(type) {
	case nil:
		return true
	default:
		return false
	}
}

func IsUint8Array(value interface{}) bool {
	switch value.(type) {
	case []uint8:
		return true
	default:
		return false
	}
}

func IsString(value interface{}) bool {
	switch value.(type) {
	case string:
		return true
	default:
		return false
	}
}

func GetString(value interface{}) string {
	if IsNull(value) {
		return ""
	}
	if IsString(value) {
		return value.(string)
	}
	if IsBool(value) {
		return strconv.FormatBool(GetBool(value))
	}
	if IsInt(value) {
		return strconv.Itoa(GetInt(value))
	}
	if IsInt64(value) {
		return strconv.FormatInt(GetInt64(value), 10)
	}
	if IsUint64(value) {
		return strconv.FormatUint(GetUint64(value), 10)
	}
	if IsFloat64(value) {
		return strconv.FormatFloat(GetFloat64(value), 'f', 6, 64)
	}
	if IsUint8Array(value) {
		return string(value.([]uint8))
	}
	return ""
}

func IsInt(value interface{}) bool {
	switch value.(type) {
	case int:
		return true
	default:
		return false
	}
}

func GetInt(value interface{}) int {
	if IsInt(value) {
		return value.(int)
	}
	if IsInt64(value) {
		return int(GetInt64(value))
	}
	if IsInt32(value) {
		return int(GetInt32(value))
	}
	if IsInt16(value) {
		return int(GetInt16(value))
	}
	if IsInt8(value) {
		return int(GetInt8(value))
	}
	return 0
}

func IsInt64(value interface{}) bool {
	switch value.(type) {
	case int64:
		return true
	default:
		return false
	}
}

func GetInt64(value interface{}) int64 {
	if IsInt64(value) {
		return value.(int64)
	}
	if IsInt32(value) {
		return int64(GetInt32(value))
	}
	if IsInt16(value) {
		return int64(GetInt16(value))
	}
	if IsInt8(value) {
		return int64(GetInt8(value))
	}
	if IsInt(value) {
		return int64(GetInt(value))
	}
	if IsUint8Array(value) {
		ret, err := strconv.ParseInt(string(value.([]uint8)), 10, 64)
		if err != nil {
			return 0
		} else {
			return ret
		}
	}
	return 0
}

func IsUint64(value interface{}) bool {
	switch value.(type) {
	case uint64:
		return true
	default:
		return false
	}
}

func GetUint64(value interface{}) uint64 {
	if IsInt64(value) {
		return value.(uint64)
	}
	return 0
}

func IsInt32(value interface{}) bool {
	switch value.(type) {
	case int32:
		return true
	default:
		return false
	}
}

func GetInt32(value interface{}) int32 {
	if IsInt32(value) {
		return value.(int32)
	}
	if IsInt64(value) {
		return int32(GetInt64(value))
	}
	if IsInt16(value) {
		return int32(GetInt16(value))
	}
	if IsInt8(value) {
		return int32(GetInt8(value))
	}
	if IsInt(value) {
		return int32(GetInt(value))
	}
	return 0
}

func IsInt16(value interface{}) bool {
	switch value.(type) {
	case int16:
		return true
	default:
		return false
	}
}

func GetInt8(value interface{}) int8 {
	if IsInt8(value) {
		return value.(int8)
	}
	if IsInt64(value) {
		return int8(GetInt64(value))
	}
	if IsInt32(value) {
		return int8(GetInt32(value))
	}
	if IsInt16(value) {
		return int8(GetInt16(value))
	}
	if IsInt(value) {
		return int8(GetInt(value))
	}
	return 0
}

func IsInt8(value interface{}) bool {
	switch value.(type) {
	case int8:
		return true
	default:
		return false
	}
}

func GetInt16(value interface{}) int16 {
	if IsInt16(value) {
		return value.(int16)
	}
	if IsInt64(value) {
		return int16(GetInt64(value))
	}
	if IsInt32(value) {
		return int16(GetInt32(value))
	}
	if IsInt8(value) {
		return int16(GetInt8(value))
	}
	if IsInt(value) {
		return int16(GetInt(value))
	}
	return 0
}

func IsFloat32(value interface{}) bool {
	switch value.(type) {
	case float32:
		return true
	default:
		return false
	}
}

func GetFloat32(value interface{}) float32 {
	if IsFloat32(value) {
		return value.(float32)
	}
	return 0
}

func IsFloat64(value interface{}) bool {
	switch value.(type) {
	case float64:
		return true
	default:
		return false
	}
}

func GetFloat64(value interface{}) float64 {
	if IsFloat64(value) {
		return value.(float64)
	}
	if IsUint8Array(value) {
		ret, err := strconv.ParseFloat(string(value.([]uint8)), 64)
		if err != nil {
			return 0
		} else {
			return ret
		}
	}
	return 0
}

func IsBool(value interface{}) bool {
	switch value.(type) {
	case bool:
		return true
	default:
		return false
	}
}

func GetBool(value interface{}) bool {
	if IsBool(value) {
		return value.(bool)
	}
	return false
}
